﻿

Namespace YahooManaged.Finance.Indicators



    Public Class WPR
        Implements IHistQuoteIndicator

        Public ReadOnly Property Name() As String Implements IIndicator.Name
            Get
                Return "Williams Percent Range"
            End Get
        End Property

        Public ReadOnly Property IsRealative As Boolean Implements IIndicator.IsRealative
            Get
                Return True
            End Get
        End Property

        Public ReadOnly Property ScaleMaximum() As Double Implements IIndicator.ScaleMaximum
            Get
                Return 100
            End Get
        End Property

        Public ReadOnly Property ScaleMinimum() As Double Implements IIndicator.ScaleMinimum
            Get
                Return 0
            End Get
        End Property


        Public Property Period() As Integer = 10 Implements IIndicator.Period


        ''' <summary>
        ''' Calculate values of Williams Percent Range for historic quote values.
        ''' </summary>
        ''' <param name="values">An unsorted IEnumerable of HistQuoteData.</param>
        ''' <returns>The sorted dictionaries. 1) WPR values; 2) Quote values (Close)</returns>
        ''' <remarks></remarks>
        Public Function Calculate(ByVal values As System.Collections.Generic.IEnumerable(Of HistQuoteData)) As System.Collections.Generic.Dictionary(Of Date, Double)() Implements IHistQuoteIndicator.Calculate
            Dim wprResult As New Dictionary(Of Date, Double)

            Dim quoteValues As New List(Of HistQuoteData)(values)
            quoteValues.Sort(New HistQuotesSorter)

            wprResult.Add(quoteValues(0).TradingDate, 50)
            For i As Integer = 1 To quoteValues.Count - 1
                Dim periodlength As Integer = Math.Min(i, Me.Period + 1)

                Dim ll As Double = quoteValues(i - periodlength).Low
                Dim hh As Double = quoteValues(i - periodlength).High

                For s As Integer = i - periodlength To i
                    If quoteValues(s).Low < ll Then ll = quoteValues(s).Low
                    If quoteValues(s).High > hh Then hh = quoteValues(s).High
                Next
                wprResult.Add(quoteValues(i).TradingDate, ((hh - quoteValues(i).Close) / (hh - ll)) * 100)
            Next
            Dim conv As New QuotesConverter
            Return New Dictionary(Of Date, Double)() {wprResult, conv.ConvertHistQuotesToSingleValues(quoteValues)}
        End Function

        Public Overrides Function ToString() As String
            Return Me.Name & " " & Me.Period
        End Function

    End Class


End Namespace